use List::*;
enum List {
//     Cons:元组结构体,包含链表的一个元素和指向下一个元素的指针
    Cons(u32, Box<List>),
//     Nil:末结点,表明链表结束
    Nil,
}
// 为enum定义方法
impl List {
//     创建一个空链表
    fn new() -> List {
    //     `Nil`为`List`类型(`Nil`的完整路径为`List::Nil`)
        Nil
    }
//     处理一个List,在其头部插入新元素,并返回该List
    fn prepend(self, elem: u32) -> List {
    //     `Cons`也为`List`类型
        Cons(elem, Box::new(self))
    }
//     返回List的长度
    fn len(&self) -> u32 {
    //     必须对`self`进行匹配(match),因为这个方法的行为取决于`self`的值
    // 取值种类。
    // `self`为`&List`类型的引用,`*self`为`List`类型,匹配一个具体的`T`
    // 类型要好过匹配引用`&T`
        match *self {
        //     不能得到tail的所有权,因为`self`是借用的
        //     因此使用一个对tail的引用
            Cons(_, ref tail) => 1 + tail.len(),
        //     基本情况:空链表没有任何元素
            Nil => 0,
        }
    }
//     返回列表的字符串表示(该字符串是堆分配)
    fn stringify(&self) -> String {
        match *self {
            Cons(head, ref tail) => {
            //     `format!`类似于`print!`,但它会返回一个堆分配的字符串,
            // 而不是将内容打印到控制台
                format!("{}, {}", head, tail.stringify())
            },
            Nil => {
                format!("Nil")
            },
        }
}
}

fn main() {
//     创建一个空链表
    let mut list = List::new();
//     追加一些元素
    list = list.prepend(1);
    list = list.prepend(2);
    list = list.prepend(3);
//     显示链表的长度
    println!("linked list has length: {}", list.len());
//     显示链表的字符串表示
    println!("{}", list.stringify());
}
